#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "list.h"
#include "user.h"
#include "book.h"
#include "recod.h"
#include "io.h"
#include "core.h"

#define HEADERBUFSIZE 10
#define COMMONBUFSIZE 2000

#ifndef NUMBERBUFSIZE
#define NUMBERBUFSIZE 10
#endif //NUMBERBUFSIZE

#ifndef ISBNBUFSIZE
#define ISBNBUFSIZE 15
#endif // ISBNBUFSIZE

#ifndef RECODNUMBUFSIZE
#define RECODNUMBUFSIZE 20
#endif // RECODNUMBUFSIZE

#ifndef NUMBERBUFSIZE
#define NUMBERBUFSIZE 10
#endif
#ifndef PASSWORDBUFSIZE
#define PASSWORDBUFSIZE 101
#endif
#ifndef TITLEBUFSIZE
#define TITLEBUFSIZE 2000
#endif
static user* login_user = NULL;

static char* admin_password = NULL;

static user* users_list = NULL;
static book* books_list = NULL;
static recod* recods_list = NULL;

void show()
{
    char target_table[7];
    do
    {
        fflush(stdin);
        printf("要显示的表(user, book, recod)：");
    }
    while(scanf("%s", &target_table) == 0);
    str_tolower(target_table);
    if(strcmp(target_table, "user") == 0)
    {
        if(users_list != NULL)
            show_user(users_list);
    }
    else if(strcmp(target_table, "book") == 0)
    {
        if(books_list != NULL)
            show_book(books_list);
    }
    else if(strcmp(target_table, "recod") == 0)
    {
        if(recods_list != NULL)
            show_recod(recods_list);
    }
    else
    {
        printf("未找到表 %s.\n", target_table);
    }
}

void sync()
{
    if(!sync_cache(users_list, books_list, recods_list))
    {
        printf("同步失败！\n");
    }
    else
    {
        printf("同步完成！\n");
    }
}

void add()
{
    char target_table[7];
    do
    {
        fflush(stdin);
        printf("要添加项目的表(user, book)：");
    }
    while(scanf("%s", &target_table) == 0);
    str_tolower(target_table);
    if(strcmp(target_table, "user") == 0)
    {
        user* new_user;
        if((new_user = create_user()) != NULL)
        {
            if(users_list == NULL)
            {
                users_list = new_user;
            }
            else
            {
                INSERT_NODE(new_user, users_list);
            }
            printf("已完成！\n");
        }
    }
    else if(strcmp(target_table, "book") == 0)
    {
        book* new_book;
        if((new_book = create_book()) != NULL)
        {
            if(books_list == NULL)
            {
                books_list = new_book;
            }
            else
            {
                INSERT_NODE(new_book, books_list);
            }
            printf("已完成！\n");
        }
    }
    else if(strcmp(target_table, "recod") == 0)
    {
        printf("请使用 \"borrow\" 命令添加记录！\n");
    }
    else
    {
        printf("未找到表 %s\n", target_table);
    }
}

void str_tolower(char* source_str)
{
    int length, i;
    length = strlen(source_str);
    for(i = 0; i < length; ++i)
    {
        source_str[i] = tolower(source_str[i]);
    }
}

void help()
{
    printf("BookManager\n");
    printf("----------初级命令----------\n");
    printf("add\t向某张表添加新项目\n");
    printf("remove\t删除某张表中的项目\n");
    printf("clean\t清除表中所有内容\n");
    printf("show\t输出表中所有内容\n");
    printf("search\t按编号搜索项目\n");
    printf("borrow\t借阅\n");
    printf("return\t归还\n");
    printf("change\t修改项目\n");
    printf("overview\t查看总览\n");
    printf("password\t修改密码\n");
    printf("sync\t将内存中的数据同步到文件\n");
    printf("exit\t退出登录\n");
    printf("----------------------------\n");
    printf("读者编号长度：9\n");
    printf("ISBN长度：13\n");
    printf("借阅记录编号长度：15\n");
}

void remove_lt()
{
    char target_table[7];
    do
    {
        fflush(stdin);
        printf("要删除项目的表(user, book, recod)：");
    }
    while(scanf("%s", &target_table) == 0);
    str_tolower(target_table);
    if(strcmp(target_table, "user") == 0)
    {
        printf("请输入要删除的读者的编号：");
        char number_buf[NUMBERBUFSIZE];
        scanf("%s", &number_buf);
        fflush(stdin);
        user* user_to_remove = search_user(users_list, number_buf);
        if(user_to_remove != NULL)
        {
            if(users_list == user_to_remove)
                users_list = user_to_remove->next;
            REMOVE_NODE(user_to_remove, user);
            printf("已完成！\n");
        }
        else
            printf("未找到读者 %s\n", number_buf);
    }
    else if(strcmp(target_table, "book") == 0)
    {
        printf("请输入要删除的图书的ISBN：");
        char isbn_buf[ISBNBUFSIZE];
        scanf("%s", &isbn_buf);
        fflush(stdin);
        book* book_to_remove = search_book(books_list, isbn_buf);
        if(book_to_remove != NULL)
        {
            if(books_list == book_to_remove)
                books_list = book_to_remove->next;
            REMOVE_NODE(book_to_remove, book);
            printf("已完成！\n");
        }
        else
            printf("未找到图书 %s\n", isbn_buf);
    }
    else if(strcmp(target_table, "recod") == 0)
    {
        printf("请输入要删除的借阅记录的编号：");
        char number_buf[RECODNUMBUFSIZE];
        scanf("%s", &number_buf);
        fflush(stdin);
        recod* recod_to_remove = search_recod(recods_list, number_buf);
        if(recod_to_remove != NULL)
        {
            if(recods_list == recod_to_remove)
                recods_list = recod_to_remove->next;
            REMOVE_NODE(recod_to_remove, recod);
            printf("已完成！\n");
        }
        else
            printf("未找到借阅记录 %s\n", number_buf);
    }
    else
    {
        printf("未找到表 %s.\n", target_table);
    }
}

void clean()
{
    char target_table[7];
    do
    {
        fflush(stdin);
        printf("要清空的表(user, book, recod)：");
    }
    while(scanf("%s", &target_table) == 0);
    str_tolower(target_table);
    if(strcmp(target_table, "user") == 0)
    {
        while(users_list != NULL)
        {
            user* current_user = users_list->next;
            REMOVE_NODE(users_list, user);
            users_list = current_user;
        }
        printf("已完成！\n");
    }
    else if(strcmp(target_table, "book") == 0)
    {
        while(books_list != NULL)
        {
            book* current_book = books_list;
            REMOVE_NODE(books_list, book);
            books_list = current_book;
        }
        printf("已完成！\n");
    }
    else if(strcmp(target_table, "recod") == 0)
    {
        while(recods_list != NULL)
        {
            recod* current_recod = recods_list;
            REMOVE_NODE(recods_list, recod);
            recods_list = current_recod;
        }
        printf("已完成！\n");
    }
    else
    {
        printf("未找到表 %s.\n", target_table);
    }
}

void initialize()
{
    users_list = create_users_list(get_users_db_path());
    books_list = create_books_list(get_books_db_path());
    recods_list = create_recods_list(get_recods_db_path());
    if((admin_password = get_admin_password()) == NULL)
    {
        char* password_temp;
        do
        {
            printf("\n首次使用请输入管理员密码：");
            password_temp = password_domain();
        }
        while(strlen(password_temp) == 0);
        admin_password = password_temp;
        set_admin_password(password_temp);
    }
}

int admin_login()
{
    printf("请输入管理员密码：");
    char* password_temp = password_domain();
    if(strcmp(admin_password, password_temp) == 0)
    {
        free(password_temp);
        return 1;
    }
    else
    {
        printf("密码错误\n");
        free(password_temp);
        return 0;
    }
}

void change_admin_password()
{
    char* password_temp;
    do
    {
        printf("请输入新密码：");
        password_temp = password_domain();
    }
    while(strlen(password_temp) == 0);
    free(admin_password);
    admin_password = password_temp;
    set_admin_password(password_temp);
    printf("已完成\n");
}

void borrow()
{
    recod* new_recod = create_recod(users_list, books_list);
    if(new_recod != NULL)
    {
        if(recods_list == NULL)
            recods_list = new_recod;
        else
        {
            INSERT_NODE(new_recod, recods_list);
        }
        printf("已完成！\n");
    }
}

void return_lt()
{
    return_book(recods_list, books_list, users_list);
}

void search()
{
    char target_table[7];
    do
    {
        fflush(stdin);
        printf("要搜索项目的表(user, book, recod)：");
    }
    while(scanf("%s", &target_table) == 0);
    str_tolower(target_table);
    if(strcmp(target_table, "user") == 0)
    {
        printf("请输入要搜素的读者的编号：");
        char number_buf[NUMBERBUFSIZE];
        scanf("%s", &number_buf);
        fflush(stdin);
        user* result_user = search_user(users_list, number_buf);
        if(result_user != NULL)
        {
            printf("编号：%s\n", result_user->number);
            printf("姓名：%s\n", result_user->name);
            printf("可借总数：%d\n", result_user->total);
            printf("可借剩余：%d\n", result_user->rest);
        }
        else
            printf("未找到读者 %s\n", number_buf);
    }
    else if(strcmp(target_table, "book") == 0)
    {
        printf("请输入要搜索的图书的ISBN：");
        char isbn_buf[ISBNBUFSIZE];
        scanf("%s", &isbn_buf);
        fflush(stdin);
        book* result_book = search_book(books_list, isbn_buf);
        if(result_book != NULL)
        {
            printf("ISBN：%s\n", result_book->isbn);
            printf("标题：%s\n", result_book->title);
            printf("作者：%s\n", result_book->author);
            printf("出版社：%s\n", result_book->press);
            printf("可借总数：%d\n", result_book->total);
            printf("可借剩余：%d\n", result_book->rest);
        }
        else
            printf("未找到图书 %s\n", isbn_buf);
    }
    else if(strcmp(target_table, "recod") == 0)
    {
        printf("请输入要搜索的借阅记录的编号：");
        char number_buf[RECODNUMBUFSIZE];
        scanf("%s", &number_buf);
        fflush(stdin);
        recod* result_recod = search_recod(recods_list, number_buf);
        if(result_recod != NULL)
        {
            printf("编号：%s\n", result_recod->number);
            printf("图书编号：%s\n", result_recod->book_num);
            printf("读者编号：%s\n", result_recod->user_num);
            printf("借出时间：%s\n", result_recod->outdate);
            if(result_recod->indate != NULL)
                printf("归还时间：%s\n", result_recod->indate);
            else
                printf("归还时间：N\\A\n");
        }
        else
            printf("未找到借阅记录 %s\n", number_buf);
    }
    else
    {
        printf("未找到表 %s.\n", target_table);
    }
}

void overview()
{
    unsigned long user_total = 0;
    unsigned long book_total_kind = 0;
    unsigned long book_total_number = 0;
    unsigned long book_rest = 0;
    unsigned long recod_total = 0;
    unsigned long recod_loan = 0;
    if(users_list != NULL)
    {
        user* current_user = users_list;
        do
        {
            ++user_total;
        }
        while((current_user = current_user->next) != NULL);
    }
    if(books_list != NULL)
    {
        book* current_book = books_list;
        do
        {
            ++book_total_kind;
            book_total_number += current_book->total;
            book_rest += current_book->rest;
        }
        while((current_book = current_book->next) != NULL);
    }
    if(recods_list != NULL)
    {
        recod* current_recod = recods_list;
        do
        {
            ++recod_total;
            if(current_recod->indate == NULL)
                ++recod_loan;
        }
        while((current_recod = current_recod->next) != NULL);
    }
    printf("-------------------------------------\n");
    printf("读者总数：%d\n", user_total);
    printf("-------------------------------------\n");
    printf("图书种类：%d\n", book_total_kind);
    printf("图书总数：%d\n", book_total_number);
    printf("可借图书：%d\n", book_rest);
    printf("-------------------------------------\n");
    printf("借阅记录总数：%d\n", recod_total);
    printf("未还记录：%d\n", recod_loan);
    printf("-------------------------------------\n");
}

void change_info()
{
    char target_table[7];
    do
    {
        fflush(stdin);
        printf("要修改信息的表(user, book, recod)：");
    }
    while(scanf("%s", &target_table) == 0);
    str_tolower(target_table);
    if(strcmp(target_table, "user") == 0)
    {
        if(users_list == NULL)
        {
            printf("表 %s 是空的\n", target_table);
            return;
        }
        char number_buf[NUMBERBUFSIZE];
        printf("要修改信息的用户的编号：");
        scanf("%s", &number_buf);
        fflush(stdin);
        user* target_user = search_user(users_list, number_buf);
        if(target_user == NULL)
        {
            printf("未找到用户 %s\n", number_buf);
            return;
        }
        char header_buf[HEADERBUFSIZE];
        while(1)
        {
            printf("要修改的字段(number,name,total)或退出(exit)：");
            scanf("%s", &header_buf);
            fflush(stdin);
            str_tolower(header_buf);
            char common_buf[COMMONBUFSIZE];
            if(strcmp(header_buf, "number") == 0)
            {
                printf("新的编号：");
                scanf("%s", &common_buf);
                fflush(stdin);
                if(strlen(common_buf) != 9)
                {
                    printf("编号应为 9 位\n");
                    continue;
                }
                free(target_user->number);
                target_user->number = strdup(common_buf);
                printf("已完成\n");
            }
            else if(strcmp(header_buf, "name") == 0)
            {
                printf("新的姓名：");
                scanf("%s", &common_buf);
                fflush(stdin);
                free(target_user->name);
                target_user->name = strdup(common_buf);
                printf("已完成\n");
            }
            else if(strcmp(header_buf, "total") == 0)
            {
                printf("新的可借总数：");
                int total_buf = 0;
                scanf("%d", &total_buf);
                fflush(stdin);
                int increase = total_buf - target_user->total;
                target_user->total = total_buf;
                target_user->rest += increase;
                printf("已完成\n");
            }
            else if(strcmp(header_buf, "exit") == 0)
                break;
            else
                printf("未找到字段 %s\n", header_buf);
        }
    }
    else if(strcmp(target_table, "book") == 0)
    {
        if(books_list == NULL)
        {
            printf("表 %s 是空的\n", target_table);
            return;
        }
        char isbn_buf[ISBNBUFSIZE];
        printf("要修改信息的图书的ISBN：");
        scanf("%s", &isbn_buf);
        fflush(stdin);
        book* target_book = search_book(books_list, isbn_buf);
        if(target_book == NULL)
        {
            printf("未找到图书 %s\n", isbn_buf);
            return;
        }
        char header_buf[HEADERBUFSIZE];
        while(1)
        {
            printf("要修改的字段(isbn,title,author,press,total)或退出(exit)：");
            scanf("%s", &header_buf);
            fflush(stdin);
            str_tolower(header_buf);
            char common_buf[COMMONBUFSIZE];
            if(strcmp(header_buf, "isbn") == 0)
            {
                printf("新的ISBN：");
                scanf("%s", common_buf);
                fflush(stdin);
                if(strlen(common_buf) != 13)
                {
                    printf("ISBN 应为 13 位\n");
                    continue;
                }
                free(target_book->isbn);
                target_book->isbn = strdup(common_buf);
                printf("已完成\n");
            }
            else if(strcmp(header_buf, "title") == 0)
            {
                printf("新的标题：");
                scanf("%s", &common_buf);
                fflush(stdin);
                free(target_book->title);
                target_book->title = strdup(common_buf);
                printf("已完成\n");
            }
            else if(strcmp(header_buf, "author") == 0)
            {
                printf("新的作者：");
                scanf("%s", &common_buf);
                fflush(stdin);
                free(target_book->author);
                target_book->author = strdup(common_buf);
                printf("已完成\n");
            }
            else if(strcmp(header_buf, "press") == 0)
            {
                printf("新的出版社：");
                scanf("%s", &common_buf);
                fflush(stdin);
                free(target_book->press);
                target_book->press = strdup(common_buf);
                printf("已完成\n");
            }
            else if(strcmp(header_buf, "total") == 0)
            {
                printf("新的可借总数：");
                int total_buf = 0;
                scanf("%d", &total_buf);
                fflush(stdin);
                int increase = total_buf - target_book->total;
                target_book->total = total_buf;
                target_book->rest += increase;
                printf("已完成\n");
            }
            else if(strcmp(header_buf, "exit") == 0)
                break;
            else
                printf("未找到字段 %s\n", header_buf);
        }
    }
    else if(strcmp(target_table, "recod") == 0)
    {
        if(recods_list == NULL)
        {
            printf("表 %s 是空的\n", target_table);
            return;
        }
        char number_buf[RECODNUMBUFSIZE];
        printf("要修改信息的记录的编号：");
        scanf("%s", &number_buf);
        fflush(stdin);
        recod* target_recod = search_recod(recods_list, number_buf);
        if(target_recod == NULL)
        {
            printf("未找到图书 %s\n", number_buf);
            return;
        }
        char header_buf[HEADERBUFSIZE];
        while(1)
        {
            printf("要修改的字段(number,book,user)或退出(exit)：");
            scanf("%s", &header_buf);
            fflush(stdin);
            str_tolower(header_buf);
            char common_buf[COMMONBUFSIZE];
            if(strcmp(header_buf, "number") == 0)
            {
                printf("新的编号：");
                scanf("%s", &common_buf);
                fflush(stdin);
                if(strlen(common_buf) != 15)
                {
                    printf("编号应为 15 位\n");
                    continue;
                }
                free(target_recod->number);
                target_recod->number = strdup(common_buf);
                printf("已完成\n");
            }
            else if(strcmp(header_buf, "book") == 0)
            {
                printf("新的ISBN：");
                scanf("%s", common_buf);
                fflush(stdin);
                if(strlen(common_buf) != 13)
                {
                    printf("ISBN 应为 13 位\n");
                    continue;
                }
                free(target_recod->book_num);
                target_recod->book_num = strdup(common_buf);
                printf("已完成\n");
            }
            else if(strcmp(header_buf, "user") == 0)
            {
                printf("新的读者编号：");
                scanf("%s", &common_buf);
                fflush(stdin);
                if(strlen(common_buf) != 9)
                {
                    printf("读者编号应为 9 位\n");
                    continue;
                }
                free(target_recod->user_num);
                target_recod->user_num = strdup(common_buf);
                printf("已完成\n");
            }
            else if(strcmp(header_buf, "exit") == 0)
                break;
            else
                printf("未找到字段 %s\n", header_buf);
        }
    }
    else
    {
        printf("未找到表 %s.\n", target_table);
    }
}

void clean_screen()
{
    system("cls");
}

void pause()
{
    system("pause");
}

/*For no-admin user*/

int user_login()
{
    char number_buf[NUMBERBUFSIZE];
    char password_buf[PASSWORDBUFSIZE];
    printf("请输入编号：");
    scanf("%s", &number_buf);
    fflush(stdin);
    while(strlen(number_buf) != 9)
    {
        printf("编号应为 9 位\n");
        scanf("%s", &number_buf);
        fflush(stdin);
    }
    if(users_list == NULL)
    {
        printf("未找到用户 %s\n", number_buf);
        return 0;
    }
    user* temp_user = search_user(users_list, number_buf);
    if(temp_user == NULL)
    {
        printf("未找到用户 %s\n", number_buf);
        return 0;
    }
    printf("请输入密码：");
    char* password_temp = password_domain();
    if(strcmp(password_temp, temp_user->password) == 0)
    {
       login_user = temp_user;
       free(password_temp);
       return 1;
    }
    else
    {
        printf("密码错误\n");
        free(password_temp);
        return 0;
    }
}

void show_tip()
{
    printf("------------------------------\n");
    printf("1.借阅图书\t2.归还图书\n");
    printf("3.浏览图书\t4.查找图书\n");
    printf("5.修改密码\t6.个人信息\n");
    printf("7.退出\n");
    printf("------------------------------\n");
    printf("输入命令：");
}

void change_password()
{
    char* password_temp;
    do
    {
        printf("请输入新密码：");
        password_temp = password_domain();
    }
    while(strlen(password_temp) == 0);
    free(login_user->password);
    login_user->password = strdup(password_temp);
    printf("完成\n");
}

void show_info()
{
    printf("编号：%s\n", login_user->number);
    printf("姓名：%s\n", login_user->name);
    printf("可借总数：%d\n", login_user->total);
    printf("可借剩余：%d\n", login_user->rest);
    printf("------------当前借阅图书列表------------\n");
    show_borrowed_books(login_user, recods_list, books_list);
    printf("-------------------END------------------\n");
}

void get_book_info()
{
    char title_buf[TITLEBUFSIZE];
    printf("请输入要查找的图书标题：");
    scanf("%s", &title_buf);
    fflush(stdin);
    if(books_list != NULL)
    {
        book* current_book = books_list;
        do
        {
            if(strcmp(current_book->title, title_buf) == 0)
            {
                printf("ISBN：%s\n", current_book->isbn);
                printf("标题：%s\n", current_book->title);
                printf("作者：%s\n", current_book->author);
                printf("出版社：%s\n", current_book->press);
                printf("可借总数：%d\n", current_book->total);
                printf("可借剩余：%d\n", current_book->rest);
                return;
            }
        }
        while((current_book = current_book->next) != NULL);
    }
    printf("未找到图书 %s\n", title_buf);
}

void interface_borrow()
{
    printf("------------当前借阅图书列表------------\n");
    show_borrowed_books(login_user, recods_list, books_list);
    printf("-------------------END------------------\n");
    recod* new_recod = interface_borrow_book(login_user, books_list);
    if(new_recod != NULL)
    {
        if(recods_list == NULL)
            recods_list = new_recod;
        else
        {
            INSERT_NODE(new_recod, recods_list);
        }
        printf("成功借出图书：\n");
        book* borrowed_book = search_book(books_list, new_recod->book_num);
        printf("ISBN：%s\n", borrowed_book->isbn);
        printf("标题：%s\n", borrowed_book->title);
    }
}

void interface_return()
{
    if(login_user->rest == login_user->total)
    {
        printf("还未借图书\n");
        return;
    }
    printf("------------当前借阅图书列表------------\n");
    show_borrowed_books(login_user, recods_list, books_list);
    printf("-------------------END------------------\n");
    interface_return_book(login_user, recods_list, books_list);
}

void user_logout()
{
    login_user = NULL;
}

void interface_show()
{
    show_book(books_list);
}

char* password_domain()
{
    char c;
    int i = 0;
    char password_buf[PASSWORDBUFSIZE];
    while((c = getch()) != '\r' && i < PASSWORDBUFSIZE)
    {
        if(c == '\b')
        {
            if(i > 0)
            {
                password_buf[--i] = 0;
                putch('\b');
                putch(' ');
                putch('\b');
            }
        }
        else
        {
            password_buf[i++] = c;
            putch('*');
        }
    }
    password_buf[i] = '\0';
    putchar('\n');
    return strdup(password_buf);
}
